﻿using UnityEditor;
using UnityEngine;
using UnityEditor.SceneManagement;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Obi{
	
	/**
	 * Custom inspector for ObiBone components.
	 * Allows particle selection and constraint edition. 
	 */
	[CustomEditor(typeof(ObiBone)), CanEditMultipleObjects] 
	public class ObiBoneEditor : ObiParticleActorEditor
	{

		public class BoneParticleProperty : ParticleProperty
		{
		  public const int Frozen = 3;

		  public BoneParticleProperty (int value) : base (value){}
		}
		
		ObiBone bone;
		
		public override void OnEnable(){
			base.OnEnable();
			bone = (ObiBone)target;

			particlePropertyNames.AddRange(new string[]{"Frozen"});
		}
		
		public override void OnDisable(){
			base.OnDisable();
			EditorUtility.ClearProgressBar();
		}

		public override void UpdateParticleEditorInformation(){
			
			for(int i = 0; i < bone.positions.Length; i++)
			{
				wsPositions[i] = bone.GetParticlePosition(i);
				facingCamera[i] = true;		
			}

		}
		
		protected override void SetPropertyValue(ParticleProperty property,int index, float value){
			if (index >= 0 && index < bone.invMasses.Length){
				switch(property){
					case ParticleProperty.Mass: 
							bone.invMasses[index] = 1.0f / Mathf.Max(value,0.00001f);
						break; 
					case ParticleProperty.Radius:
							bone.solidRadii[index] = value;
						break;
					case BoneParticleProperty.Frozen:
							bone.frozen[index] = value >= 1;
						break;
				}
			}
		}
		
		protected override float GetPropertyValue(ParticleProperty property, int index){
			if (index >= 0 && index < bone.invMasses.Length){
				switch(property){
					case ParticleProperty.Mass:
						return 1.0f/bone.invMasses[index];
					case ParticleProperty.Radius:
						return bone.solidRadii[index];
					case BoneParticleProperty.Frozen:
						return bone.frozen[index] ? 1 : 0;
				}
			}
			return 0;
		}

		public override void OnInspectorGUI() {
			
			serializedObject.Update();

			GUI.enabled = bone.Initialized;
			EditorGUI.BeginChangeCheck();
			editMode = GUILayout.Toggle(editMode,new GUIContent("Edit particles",Resources.Load<Texture2D>("EditParticles")),"LargeButton");
			if (EditorGUI.EndChangeCheck()){
				SceneView.RepaintAll();
			}
			GUI.enabled = true;			

			EditorGUILayout.LabelField("Status: "+ (bone.Initialized ? "Initialized":"Not initialized"));

			if (GUILayout.Button("Initialize")){
				if (!bone.Initialized){
					CoroutineJob job = new CoroutineJob();
					routine = EditorCoroutine.StartCoroutine(job.Start(bone.GeneratePhysicRepresentationForMesh()));
					EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
				}else{
					if (EditorUtility.DisplayDialog("Actor initialization","Are you sure you want to re-initialize this actor?","Ok","Cancel")){
						CoroutineJob job = new CoroutineJob();
						routine = EditorCoroutine.StartCoroutine(job.Start(bone.GeneratePhysicRepresentationForMesh()));
						EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
					}
				}
			}

			EditorGUI.BeginChangeCheck();
			ObiSolver solver = EditorGUILayout.ObjectField("Solver",bone.Solver, typeof(ObiSolver), true) as ObiSolver;
			if (EditorGUI.EndChangeCheck()){
				Undo.RecordObject(bone, "Set solver");
				bone.Solver = solver;
			}

			bool newSelfCollisions = EditorGUILayout.Toggle(new GUIContent("Self collisions","Enabling this allows particles generated by this actor to interact with each other."),bone.SelfCollisions);
			if (bone.SelfCollisions != newSelfCollisions){
				Undo.RecordObject(bone, "Set self collisions");
				bone.SelfCollisions = newSelfCollisions;
			}

			Editor.DrawPropertiesExcluding(serializedObject,"m_Script","chainLinks");

			// Progress bar:
			EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...",routine);
			
			// Apply changes to the serializedProperty
			if (GUI.changed){
				serializedObject.ApplyModifiedProperties();
			}
			
		}
		
	}
}


